package com.yh.csx.crm.appapi.controller;

import com.alibaba.fastjson.JSON;
import com.yh.csx.crm.core.constant.Constant;
import com.yh.csx.crm.core.entity.CommonResponse;
import com.yh.csx.crm.core.enums.ArchiveCategoryEnum;
import com.yh.csx.crm.core.enums.CooperationModeEnum;
import com.yh.csx.crm.core.enums.CustomerStatusEnum;
import com.yh.csx.crm.core.enums.PaymentDaysEnum;
import com.yh.csx.crm.core.enums.PaymentModeEnum;
import com.yh.csx.crm.core.enums.PaymentTermsEnum;
import com.yh.csx.crm.core.enums.TaxesCategoryEnum;
import com.yh.csx.crm.core.util.BeanUtils;
import com.yh.csx.crm.core.util.DateUtils;
import com.yh.csx.crm.dao.SysCustomerCategoryMapper;
import com.yh.csx.crm.po.Approval;
import com.yh.csx.crm.po.ApprovalCompleted;
import com.yh.csx.crm.qo.CustomerQo;
import com.yh.csx.crm.service.ApprovalService;
import com.yh.csx.crm.service.CategoryService;
import com.yh.csx.crm.service.CustomerService;
import com.yh.csx.crm.service.CustomerVisitService;
import com.yh.csx.crm.service.ProvinceService;
import com.yh.csx.crm.service.request.AppCustomerSearchReq;
import com.yh.csx.crm.service.response.*;
import com.yh.csx.crm.service.vo.ApprovalStatus;
import com.yh.csx.crm.service.vo.FlowNodeJSON;
import com.yh.csx.crm.service.vo.PageWrap;
import com.yh.csx.crm.service.vo.User;
import com.yh.csx.crm.vo.CustomerDetailVo;
import com.yh.csx.crm.vo.CustomerInfoVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author Huang Zhaoping
 * @date 2019/3/1
 */
@Api("APP-客户服务")
@RestController
@RequestMapping("/app/customer")
public class AppCustomerController extends BaseController {

    @Autowired
    private CustomerService customerService;

    @Autowired
    private ApprovalService approvalService;

    @Autowired
    private CustomerVisitService customerVisitService;

    @Autowired
    private ProvinceService provinceService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    SysCustomerCategoryMapper sysCustomerCategoryMapper;

    @ApiOperation("查询客户列表")
    @GetMapping("/list")
    public CommonResponse<PageWrap<AppCustomerItemResp>> customerList(AppCustomerSearchReq req) {
        return super.visit(() -> {
            CustomerQo qo = BeanUtils.convert(CustomerQo.class, req);
            // 频次
            if (req.getOrderRate() != null) {
                if (req.getOrderRate() == 0) {
                    qo.setMaxOrderCount(0);
                } else if (req.getOrderRate() == 1) {
                    qo.setMinOrderCount(1);
                    qo.setMaxOrderCount(20);
                } else if (req.getOrderRate() == 2) {
                    qo.setMinOrderCount(21);
                }
            }
            if (StringUtils.isNotBlank(req.getLocation())) {
                String[] values = req.getLocation().split(",");
                qo.setLatitude(Double.valueOf(values[0]));
                qo.setLongitude(Double.valueOf(values[1]));
            }
            qo.setSalesUserId(super.getUserId());
            qo.setNotCustomerStatusList(Arrays.asList(CustomerStatusEnum.REJECT.getCode()));
            List<CustomerInfoVo> customerList = customerService.findCustomerInfoList(qo);
            return PageWrap.wrap(customerList, vo -> {
                // 预留以后设置标签等信息
                return BeanUtils.convert(AppCustomerItemResp.class, vo);
            });
        });
    }

    @ApiOperation("查询客户详情")
    @GetMapping("/detail/{id}")
    public CommonResponse<AppCustomerDetailResp> customerDetail(@PathVariable Long id) {
        return super.visit(() -> {
            CustomerDetailVo detailVo = customerService.findCustomerDetail(id);
            if (detailVo == null) return null;
            AppCustomerDetailResp resp = BeanUtils.convert(AppCustomerDetailResp.class, detailVo);
            resp.setSalesProvinceName(provinceService.getProvinceName(resp.getSalesProvince()));
            resp.setCategoryFullName(categoryService.getCategoryFullName(resp.getFirstCategoryCode(), resp.getSecondCategoryCode()));
            // 待审批、审配中获取审批信息
            String customerStatus = resp.getCustomerStatus();
            if (CustomerStatusEnum.PENDING.getCode().equals(customerStatus)) {
                AppCustomerDetailResp.ApprovalState state = new AppCustomerDetailResp.ApprovalState();
                state.setCurrentName("待提交");
                state.setLastName("新建");
                resp.setApprovalState(state);
            }
            else if (CustomerStatusEnum.ONGOING.getCode().equals(customerStatus) || CustomerStatusEnum.REJECT.getCode().equals(customerStatus)) {
                Approval approval = approvalService.findPendingApproval(resp.getId());
                if (approval != null) {
                    String currentNode = String.valueOf(approval.getCurrentNodeCode());
                    List<FlowNodeJSON> flowList = JSON.parseArray(approval.getFlowNode(), FlowNodeJSON.class);
                    FlowNodeJSON.Node last = null, current = null, next = null;
                    for (int i = 0; i < flowList.size(); i++) {
                        FlowNodeJSON node = flowList.get(i);
                        if (Objects.equals(node.getNode().getCode(), currentNode)) {
                            current = node.getNode();
                            if (i > 0) last = flowList.get(i - 1).getNode();
                            if (i < flowList.size() - 1) next = flowList.get(i + 1).getNode();
                        }
                    }
                    AppCustomerDetailResp.ApprovalState state = new AppCustomerDetailResp.ApprovalState();
                    if (last != null) {
                        state.setLastNode(last.getCode());
                        state.setLastName(last.getName());
                    }
                    if (current != null) {
                        state.setCurrentNode(current.getCode());
                        state.setCurrentName(current.getName());
                    }
                    if (next != null) {
                        state.setNextNode(next.getCode());
                        state.setNextName(next.getName());
                    }
                    state.setApprovalId(approval.getId());
                    resp.setApprovalState(state);
                }
            }
            if (StringUtils.isNotBlank(resp.getFilePath())) {
                resp.setFileList(JSON.parseArray(resp.getFilePath(), AppCustomerDetailResp.FileInfo.class));
            } else {
                resp.setFileList(Collections.emptyList());
            }
            // 今日任务
            List<AppSalesTask> taskList = new ArrayList<>();
            if (resp.getSurplusCredit() != null) {
                taskList.add(new AppSalesTask(Constant.SALES_TASK_CREDIT_WARNING, "客户低信控预警", "及时催促回款", resp.getId(), resp.getCustomerNumber()));
            } else {
                BigDecimal surplusCredit = resp.getCreditLimit() == null ? BigDecimal.ZERO : resp.getCreditLimit();
                if (resp.getTempCreditLimit() != null && resp.getTempBeginTime() != null && resp.getTempEndTime() != null) {
                    if (DateUtils.belongCalendar(new Date(), resp.getTempBeginTime(), resp.getTempEndTime())) {
                        surplusCredit = surplusCredit.add(resp.getTempCreditLimit());
                    }
                }
                resp.setSurplusCredit(surplusCredit);
            }
            if (resp.getReceivableAmount() != null && resp.getReceivableAmount().compareTo(BigDecimal.ZERO) > 0) {
                taskList.add(new AppSalesTask(Constant.SALES_TASK_RECEIVABLE_AMOUNT, "应收账款", "查看详情", resp.getId(), resp.getCustomerNumber()));
            }
            resp.setTaskList(taskList);
            // 拜访记录
            resp.setVisitList(BeanUtils.convertList(AppCustomerVisitResp.class, customerVisitService.findCustomerLastOneForEachType(id), (t, r) -> {
                if (t.getVisitImgsUrl() != null) r.setVisitImgs(t.getVisitImgsUrl().split(","));
            }));
            return resp;
        });
    }

    @ApiOperation("修改客户业务员")
    @PostMapping("/sales")
    public CommonResponse<Void> changeCustomerSales(Long customerId, Long salesUserId) {
        return super.visit(() -> {
            User user = new User(super.getUserId(), super.getUserName());
            customerService.changeCustomer(user, customerId, salesUserId);
        });
    }


    @ApiOperation("信控大客户详情")
    @GetMapping("/big/customer/info")
    public CommonResponse<CustomerAddBigResp> getBigInfo(Long approvalId) {
        return super.visit(() -> {
            SnapshotCompareResp snapshotCompareResp = approvalService.approvalDetails(approvalId);

            CustomerAddBigResp customerAddReq = BeanUtils.convert(CustomerAddBigResp.class, snapshotCompareResp.getNewData());

//            customerAddReq.setArchiveCategory(ArchiveCategoryEnum.resolveName(customerAddReq.getArchiveCategory()));
            customerAddReq.setCooperationMode(CooperationModeEnum.resolveName(customerAddReq.getCooperationMode()));
            customerAddReq.setPaymentTerms(PaymentTermsEnum.getName(customerAddReq.getPaymentTerms()));
            customerAddReq.setTaxesCategory(TaxesCategoryEnum.resolveName(customerAddReq.getTaxesCategory()));
            customerAddReq.setPaymentDays(PaymentDaysEnum.resolveName(customerAddReq.getPaymentDays()));
            customerAddReq.setPayMode(PaymentModeEnum.resolveName(customerAddReq.getPayMode()));
            customerAddReq.setAddressDetails(snapshotCompareResp.getNewData().getRegionProvinceName() + snapshotCompareResp.getNewData().getRegionCity() + snapshotCompareResp.getNewData().getRegionArea() + snapshotCompareResp.getNewData().getAddressDetails());
            customerAddReq.setFirstCategoryCode(sysCustomerCategoryMapper.selecParentCustermType(customerAddReq.getId()));
            customerAddReq.setSecondCategoryCode(sysCustomerCategoryMapper.selecSonCustermType(customerAddReq.getId()));

            ApprovalStatus approvalStatus = approvalService.getApprovalStatus(approvalId);
            List<ApprovalCompleted> approvalCompletedList = approvalStatus.getApprovalCompletedList();
            if (approvalCompletedList != null && approvalCompletedList.size() > 0) {
                customerAddReq.setRejectReason(approvalCompletedList.get(0).getRejectReason());
            }
            customerAddReq.setStatus(approvalStatus.getApproval().getStatus());

            return customerAddReq;
        });
    }

    @ApiOperation("根据客户id获得草稿")
    @GetMapping("/big/custoner/draft/info")
    public CommonResponse<CustomerAddBigResp> getDraftInfo(Long userId){
        return super.visit(() -> {
            CustomerAddBigResp customerAddReq =  approvalService.getDraftInfo(userId);
            customerAddReq.setArchiveCategory(ArchiveCategoryEnum.resolveName(customerAddReq.getArchiveCategory()));
            customerAddReq.setCooperationMode(CooperationModeEnum.resolveName(customerAddReq.getCooperationMode()));
            customerAddReq.setPaymentTerms(PaymentTermsEnum.getName(customerAddReq.getPaymentTerms()));
            customerAddReq.setTaxesCategory(TaxesCategoryEnum.resolveName(customerAddReq.getTaxesCategory()));
            customerAddReq.setPaymentDays(PaymentDaysEnum.resolveName(customerAddReq.getPaymentDays()));
            customerAddReq.setPayMode(PaymentModeEnum.resolveName(customerAddReq.getPayMode()));
            customerAddReq.setType(customerService.getOldCustomerType(customerAddReq.getCustomerCategoryId()));
            customerAddReq.setAddressDetails(customerAddReq.getRegionProvinceName() + customerAddReq.getRegionCity() + customerAddReq.getRegionArea() + customerAddReq.getAddressDetails());
            customerAddReq.setFirstCategoryCode(sysCustomerCategoryMapper.selecParentCustermType(customerAddReq.getId()));
            customerAddReq.setSecondCategoryCode(sysCustomerCategoryMapper.selecSonCustermType(customerAddReq.getId()));
            return customerAddReq;
        });
    }

}
